package org.example.taobao.demo.order.service;

import lombok.*;
import org.example.taobao.demo.order.config.GoodProperties;
import org.example.taobao.demo.order.config.UserBalanceConfig;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * @author liwei
 * @date 2022/6/11 6:41 PM
 */
@Service
@RequiredArgsConstructor
public class OrderService {
    private final RestTemplate restTemplate;
    private final GoodProperties goodProperties;
    private final UserBalanceConfig.UserBalance userBalance;

    public boolean purchase(String goodId, Integer number) {
        // 查询产品
        GoodVO good = getGood(goodId);
        Assert.isTrue(good.getStock().compareTo(number) >=0, good.getGoodName()+"商品库存不足");

        // 计算总价
        BigDecimal totalPrice = calculateTotal(good.getPrice(), number);

        Assert.isTrue(userBalance.getBalance().compareTo(totalPrice) >=0, "余额不足");

        // 扣减余额
        deductUserBalance(totalPrice);

        // 扣减商品库存
        return deductStock(goodId, number);
    }

    private void deductUserBalance(BigDecimal totalPrice) {
        userBalance.getBalance().subtract(totalPrice);
    }

    private BigDecimal calculateTotal(BigDecimal price, Integer number) {
        return price.multiply(new BigDecimal(number));
    }

    private GoodVO getGood(String goodId) {
        String queryGoodServiceUrl = String.format(goodProperties.getQueryGoodServiceUrl(), goodId);
        return restTemplate.getForObject(queryGoodServiceUrl, GoodVO.class);
    }

    private boolean deductStock(String goodId, Integer number) {
        return Boolean.TRUE.equals(restTemplate.postForObject(goodProperties.getDeductGoodStockServiceUrl(), new DeductStockVO(goodId, number), Boolean.class));
    }

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    static class DeductStockVO implements Serializable {
        private String goodId;
        private Integer number;
    }

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter
    static class GoodVO implements Serializable {
        private String goodId;
        private String goodName;
        private Integer stock;
        private BigDecimal price;
    }

}
